/**
 *  @file WriteCharHelper.cpp
 */
#include "WriteCharHelper.h"
#include "../../common/CppflibMain.h"

using namespace cppflib::collections;
using namespace cppflib::text;

namespace cppflib
{

namespace io
{

/**
 *  Write characters from source string to target buffer. Character conversion is performed
 *  based on the character set requested.
 *
 *  @param [in] pSrc -- pointer to src string
 *  @param [in] len -- length of source string
 *  @param [in, out] outBuf -- output buffer
 *  @param [in] targetCharSet -- output character set
 */
void WriteCharsToBuffer(pcwstr_t pSrc, u32_t srcLen, BinBuf &outBuf, charset_t targetCharSet)
{
   const int MAXNEWLINE_CHARLEN = 2;

   if (targetCharSet == text::CS_UTF8) {
      int utf8Len = 0;

      if (pSrc && srcLen > 0) {
         utf8Len = text::UTF16ToUTF8(pSrc, srcLen, NULL, 0);
         outBuf.Realloc(utf8Len + MAXNEWLINE_CHARLEN);
         text::UTF16ToUTF8(pSrc, srcLen, reinterpret_cast<char*>(outBuf.GetRawBuf()), utf8Len);
      }
      outBuf.SetValidLength(utf8Len);
   }
   else if ((targetCharSet == text::CS_UTF16LE && cppflib::IsLittleEndian()) ||
            (targetCharSet == text::CS_UTF16BE && !cppflib::IsLittleEndian()) ) {
      // output same as string's endianess
      outBuf.SetValidLength(0);

      if (pSrc && srcLen > 0) {
         outBuf.Realloc((srcLen + MAXNEWLINE_CHARLEN) * sizeof(wc_t));
         outBuf.CopyData(reinterpret_cast<const u8_t*>(pSrc), srcLen * sizeof(wc_t));
      }

   }
   else if ((targetCharSet == text::CS_UTF16LE && !cppflib::IsLittleEndian()) ||
            (targetCharSet == text::CS_UTF16BE && cppflib::IsLittleEndian()) ) {
      // output different as string's endianess
      outBuf.SetValidLength(0);

      if (pSrc && srcLen > 0) {
         u8_t tempBuf[2];
         u8_t *pChar = reinterpret_cast<u8_t*>(const_cast<pwstr_t>(pSrc));
      
         outBuf.Realloc((srcLen + MAXNEWLINE_CHARLEN) * sizeof(wc_t));
         outBuf.SetValidLength(0);
         for (int i = 0; i < static_cast<int>(srcLen); ++i) {
            // reverse endianess of each character
            tempBuf[1] = *pChar++;
            tempBuf[0] = *pChar++;
            outBuf.AppendData(tempBuf, 2);
         }
      }
   }

}

} // end of namespace io

} // end of namespace cppflib
